home *** CD-ROM | disk | FTP | other *** search
/ Programming Windows (5th Edition) / Programming Windows, 5th ed. - Companion CD (097-0002183)(1999).iso / Chap07 / Checker4 / Checker4.c next >
Encoding:
C/C++ Source or Header  |  1998-10-09  |  6.8 KB  |  213 lines

  1. /*-------------------------------------------------
  2.    CHECKER4.C -- Mouse Hit-Test Demo Program No. 4
  3.                  (c) Charles Petzold, 1998
  4.   -------------------------------------------------*/
  5.  
  6. #include <windows.h>
  7.  
  8. #define DIVISIONS 5
  9.  
  10. LRESULT CALLBACK WndProc   (HWND, UINT, WPARAM, LPARAM) ;
  11. LRESULT CALLBACK ChildWndProc (HWND, UINT, WPARAM, LPARAM) ;
  12.  
  13. int   idFocus = 0 ;
  14. TCHAR szChildClass[] = TEXT ("Checker4_Child") ;
  15.  
  16. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
  17.                     PSTR szCmdLine, int iCmdShow)
  18. {
  19.      static TCHAR szAppName[] = TEXT ("Checker4") ;
  20.      HWND         hwnd ;
  21.      MSG          msg ;
  22.      WNDCLASS     wndclass ;
  23.      
  24.      wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
  25.      wndclass.lpfnWndProc   = WndProc ;
  26.      wndclass.cbClsExtra    = 0 ;
  27.      wndclass.cbWndExtra    = 0 ;
  28.      wndclass.hInstance     = hInstance ;
  29.      wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
  30.      wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
  31.      wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
  32.      wndclass.lpszMenuName  = NULL ;
  33.      wndclass.lpszClassName = szAppName ;
  34.      
  35.      if (!RegisterClass (&wndclass))
  36.      {
  37.           MessageBox (NULL, TEXT ("Program requires Windows NT!"), 
  38.                       szAppName, MB_ICONERROR) ;
  39.           return 0 ;
  40.      }
  41.      
  42.      wndclass.lpfnWndProc   = ChildWndProc ;
  43.      wndclass.cbWndExtra    = sizeof (long) ;
  44.      wndclass.hIcon         = NULL ;
  45.      wndclass.lpszClassName = szChildClass ;
  46.      
  47.      RegisterClass (&wndclass) ;
  48.      
  49.      hwnd = CreateWindow (szAppName, TEXT ("Checker4 Mouse Hit-Test Demo"),
  50.                           WS_OVERLAPPEDWINDOW,
  51.                           CW_USEDEFAULT, CW_USEDEFAULT,
  52.                           CW_USEDEFAULT, CW_USEDEFAULT,
  53.                           NULL, NULL, hInstance, NULL) ;
  54.      
  55.      ShowWindow (hwnd, iCmdShow) ;
  56.      UpdateWindow (hwnd) ;
  57.      
  58.      while (GetMessage (&msg, NULL, 0, 0))
  59.      {
  60.           TranslateMessage (&msg) ;
  61.           DispatchMessage (&msg) ;
  62.      }
  63.      return msg.wParam ;
  64. }
  65.  
  66. LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  67. {
  68.      static HWND hwndChild[DIVISIONS][DIVISIONS] ;
  69.      int         cxBlock, cyBlock, x, y ;
  70.      
  71.      switch (message)
  72.      {
  73.      case WM_CREATE :
  74.           for (x = 0 ; x < DIVISIONS ; x++)
  75.                for (y = 0 ; y < DIVISIONS ; y++)
  76.                     hwndChild[x][y] = CreateWindow (szChildClass, NULL,
  77.                               WS_CHILDWINDOW | WS_VISIBLE,
  78.                               0, 0, 0, 0,
  79.                               hwnd, (HMENU) (y << 8 | x),
  80.                               (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE),
  81.                               NULL) ;
  82.           return 0 ;
  83.                
  84.      case WM_SIZE :
  85.           cxBlock = LOWORD (lParam) / DIVISIONS ;
  86.           cyBlock = HIWORD (lParam) / DIVISIONS ;
  87.           
  88.           for (x = 0 ; x < DIVISIONS ; x++)
  89.                 for (y = 0 ; y < DIVISIONS ; y++)
  90.                     MoveWindow (hwndChild[x][y],
  91.                                 x * cxBlock, y * cyBlock,
  92.                                 cxBlock, cyBlock, TRUE) ;
  93.           return 0 ;
  94.                        
  95.      case WM_LBUTTONDOWN :
  96.           MessageBeep (0) ;
  97.           return 0 ;
  98.  
  99.           // On set-focus message, set focus to child window
  100.  
  101.      case WM_SETFOCUS:
  102.           SetFocus (GetDlgItem (hwnd, idFocus)) ;
  103.           return 0 ;
  104.  
  105.           // On key-down message, possibly change the focus window
  106.  
  107.      case WM_KEYDOWN:
  108.           x = idFocus & 0xFF ;
  109.           y = idFocus >> 8 ;
  110.  
  111.           switch (wParam)
  112.           {
  113.           case VK_UP:    y-- ;                    break ;
  114.           case VK_DOWN:  y++ ;                    break ;
  115.           case VK_LEFT:  x-- ;                    break ;
  116.           case VK_RIGHT: x++ ;                    break ;
  117.           case VK_HOME:  x = y = 0 ;              break ;
  118.           case VK_END:   x = y = DIVISIONS - 1 ;  break ;
  119.           default:       return 0 ;
  120.           }
  121.  
  122.           x = (x + DIVISIONS) % DIVISIONS ;
  123.           y = (y + DIVISIONS) % DIVISIONS ;
  124.  
  125.           idFocus = y << 8 | x ;
  126.  
  127.           SetFocus (GetDlgItem (hwnd, idFocus)) ;
  128.           return 0 ;
  129.  
  130.      case WM_DESTROY :
  131.           PostQuitMessage (0) ;
  132.           return 0 ;
  133.      }
  134.      return DefWindowProc (hwnd, message, wParam, lParam) ;
  135. }
  136.  
  137. LRESULT CALLBACK ChildWndProc (HWND hwnd, UINT message, 
  138.                                WPARAM wParam, LPARAM lParam)
  139. {
  140.      HDC         hdc ;
  141.      PAINTSTRUCT ps ;
  142.      RECT        rect ;
  143.      
  144.      switch (message)
  145.      {
  146.      case WM_CREATE :
  147.           SetWindowLong (hwnd, 0, 0) ;       // on/off flag
  148.           return 0 ;
  149.  
  150.      case WM_KEYDOWN:
  151.                // Send most key presses to the parent window
  152.           
  153.           if (wParam != VK_RETURN && wParam != VK_SPACE)
  154.           {
  155.                SendMessage (GetParent (hwnd), message, wParam, lParam) ;
  156.                return 0 ;
  157.           }
  158.                // For Return and Space, fall through to toggle the square
  159.           
  160.      case WM_LBUTTONDOWN :
  161.           SetWindowLong (hwnd, 0, 1 ^ GetWindowLong (hwnd, 0)) ;
  162.           SetFocus (hwnd) ;
  163.           InvalidateRect (hwnd, NULL, FALSE) ;
  164.           return 0 ;
  165.  
  166.                // For focus messages, invalidate the window for repaint
  167.           
  168.      case WM_SETFOCUS:
  169.           idFocus = GetWindowLong (hwnd, GWL_ID) ;
  170.  
  171.                // Fall through
  172.  
  173.      case WM_KILLFOCUS:
  174.           InvalidateRect (hwnd, NULL, TRUE) ;
  175.           return 0 ;
  176.           
  177.      case WM_PAINT :
  178.           hdc = BeginPaint (hwnd, &ps) ;
  179.           
  180.           GetClientRect (hwnd, &rect) ;
  181.           Rectangle (hdc, 0, 0, rect.right, rect.bottom) ;
  182.  
  183.                // Draw the "x" mark
  184.           
  185.           if (GetWindowLong (hwnd, 0))
  186.           {
  187.                MoveToEx (hdc, 0,          0, NULL) ;
  188.                LineTo   (hdc, rect.right, rect.bottom) ;
  189.                MoveToEx (hdc, 0,          rect.bottom, NULL) ;
  190.                LineTo   (hdc, rect.right, 0) ;
  191.           }
  192.  
  193.                // Draw the "focus" rectangle
  194.           
  195.           if (hwnd == GetFocus ())
  196.           {
  197.                rect.left   += rect.right / 10 ;
  198.                rect.right  -= rect.left ;
  199.                rect.top    += rect.bottom / 10 ;
  200.                rect.bottom -= rect.top ;
  201.  
  202.                SelectObject (hdc, GetStockObject (NULL_BRUSH)) ;
  203.                SelectObject (hdc, CreatePen (PS_DASH, 0, 0)) ;
  204.                Rectangle (hdc, rect.left, rect.top, rect.right, rect.bottom) ;
  205.                DeleteObject (SelectObject (hdc, GetStockObject (BLACK_PEN))) ;
  206.           }
  207.  
  208.           EndPaint (hwnd, &ps) ;
  209.           return 0 ;
  210.      }
  211.      return DefWindowProc (hwnd, message, wParam, lParam) ;
  212. }
  213.